/*
		ServEngine framework library
		A library to fast develop JEE online applications
	
		Copyright 2008 José Ignacio de Córdoba Álvaro

		Licensed under the Apache License, Version 2.0 (the "License");
		you may not use this file except in compliance with the License.
		You may obtain a copy of the License at

				http://www.apache.org/licenses/LICENSE-2.0

		Unless required by applicable law or agreed to in writing, software
		distributed under the License is distributed on an "AS IS" BASIS,
		WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
		See the License for the specific language governing permissions and
		limitations under the License.
	
		Jose Ignacio de Cordoba Alvaro
		http://ignacio.decordoba.com
*/

package com.servengine.struts;

import java.beans.IntrospectionException;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.io.IOException;

import java.lang.reflect.InvocationTargetException;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Convenience class including methods for easier date handling.
 */
public class ValidatorForm extends org.apache.struts.validator.ValidatorForm
{
	public static Integer[] daysOfMonth = new Integer[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
	public static Integer[] months = new Integer[]{1,2,3,4,5,6,7,8,9,10,11,12};
	public ValidatorForm() {super();}
	public Integer[] getHours()
	{
		Integer[] hours = new Integer[24];
		for (int i=0; i<24; i++)
			hours[i]=i;
		return hours;
	}
	public Integer[] getMinutes()
	{
		Integer[] minutes = new Integer[60];
		for (int i=0; i<60; i++)
			minutes[i]=i;
		return minutes;
	}
	/**
	 * @deprecated Please use getDaysOfMonth()
	 * @return
	 */
	public Integer[] getDaysofmonth()
	{
		return getDaysOfMonth();
	}
	public Integer[] getDaysOfMonth()
	{
		return daysOfMonth;
	}
	public Integer[] getMonths()
	{
		return new Integer[]{1,2,3,4,5,6,7,8,9,10,11,12};
	}
	public Integer[] getYears()
	{
		return getLastYears(100);
	}
	public Integer[] getLastYears(int howmany)
	{
		int year = GregorianCalendar.getInstance().get(Calendar.YEAR);
		Integer[] years = new Integer[howmany];
		for (int i=0; i<howmany; i++)
			years[i]=i+1+year-howmany;
		return years;
	}
	public Integer[] getYearsInverted()
	{
		return getLastYearsInverted(100);
	}
	public Integer[] getLastYearsInverted(int howmany)
	{
		int year = GregorianCalendar.getInstance().get(Calendar.YEAR);
		Integer[] years = new Integer[howmany];
		for (int i=year; -i+year<howmany; i--)
			years[-i+year]=i;
		return years;
	}
	protected Calendar getCalendarZero()
	{
	  Calendar calendar = GregorianCalendar.getInstance();
	  calendar.set(Calendar.HOUR_OF_DAY,0);
	  calendar.set(Calendar.MINUTE,0);
	  calendar.set(Calendar.SECOND,0);
	  calendar.set(Calendar.MILLISECOND,0);
		return calendar;
	}
	protected Calendar getFirstDayInMonth()
	{
		Calendar calendar = getCalendarZero();
		calendar.set(Calendar.DAY_OF_MONTH,1);
		return calendar;
	}
	protected Calendar getLastDayInMonth()
	{
	  Calendar calendar = getCalendarZero();
		calendar.set(Calendar.MONTH,calendar.get(Calendar.MONTH)+1);
	  calendar.set(Calendar.DAY_OF_MONTH,1);
		calendar.add(Calendar.SECOND,-1);
		return calendar;
	}
	
	protected PropertyDescriptor getPropertyDescriptor(String propertyName) throws IntrospectionException
	{
	  for (PropertyDescriptor aux: Introspector.getBeanInfo( this.getClass()).getPropertyDescriptors())
	    if (aux.getName().equals(propertyName))
	      return aux;
		throw new IntrospectionException("No such property in Class: "+propertyName);
	}

	public java.util.Calendar getCalendarFromProperty(PropertyDescriptor propertyDescriptor, boolean createIfNull) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  java.lang.reflect.Method getter = propertyDescriptor.getReadMethod();
	  Calendar calendar = null;
		try
		{
			calendar = (Calendar)getter.invoke(this,null);
		} catch (ClassCastException e)
		{
			Date date = (Date)getter.invoke(this,null);// Si salta ClassCast, a tomar por culo, claro... ni Calendar ni Date...
			if (date!=null)
			{
				calendar = GregorianCalendar.getInstance();
				calendar.setTime(date); 
			}
		}
	  return calendar==null&&createIfNull? getCalendarZero() : calendar;
	}

	public void setPropertyFromCalendar(PropertyDescriptor propertyDescriptor, Calendar calendar) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  java.lang.reflect.Method setter = propertyDescriptor.getWriteMethod();
	  try
		{
		  Object[] args = {calendar};
			setter.invoke(this,args);
		} catch (IllegalArgumentException e)
		{
		  Object[] args = {calendar.getTime()};
		  setter.invoke(this,args);
		}
	}

	public void setMinute(String propertyName, Integer value) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
		if (value==null)
			return;
		PropertyDescriptor propertyDescriptor = getPropertyDescriptor(propertyName);
	  Calendar calendar = getCalendarFromProperty(propertyDescriptor,true);
		calendar.set(Calendar.MINUTE,value);
		setPropertyFromCalendar(propertyDescriptor,calendar);
	}
	public Integer getMinute(String propertyName) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
		Calendar calendar = getCalendarFromProperty(getPropertyDescriptor(propertyName),false);
		return calendar==null?null:calendar.get(Calendar.MINUTE);
	}
	public void setHour(String propertyName, Integer value) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  if (value==null)
	    return;
		PropertyDescriptor propertyDescriptor = getPropertyDescriptor(propertyName);
	  Calendar calendar = getCalendarFromProperty(propertyDescriptor,true);
		calendar.set(Calendar.HOUR_OF_DAY,value);
	  setPropertyFromCalendar(propertyDescriptor,calendar);
	}
	public Integer getHour(String propertyName) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  Calendar calendar = getCalendarFromProperty(getPropertyDescriptor(propertyName),false);
		return calendar==null?null:calendar.get(Calendar.HOUR_OF_DAY);
	}
	public void setDay(String propertyName, Integer value) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  if (value==null)
	    return;
	  PropertyDescriptor propertyDescriptor = getPropertyDescriptor(propertyName);
	  Calendar calendar = getCalendarFromProperty(propertyDescriptor,true);
		calendar.set(Calendar.DAY_OF_MONTH,value);
	  setPropertyFromCalendar(propertyDescriptor,calendar);
	}
	public Integer getDay(String propertyName) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  Calendar calendar = getCalendarFromProperty(getPropertyDescriptor(propertyName),false);
	  return calendar==null?null:calendar.get(Calendar.DAY_OF_MONTH);
	}
	public void setMonth(String propertyName, Integer value) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  if (value==null)
	    return;
		PropertyDescriptor propertyDescriptor = getPropertyDescriptor(propertyName);
	  Calendar calendar = getCalendarFromProperty(propertyDescriptor,true);
		calendar.set(Calendar.MONTH,value-1);
	  setPropertyFromCalendar(propertyDescriptor,calendar);
	}
	public Integer getMonth(String propertyName) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  Calendar calendar = getCalendarFromProperty(getPropertyDescriptor(propertyName),false);
		return calendar==null?null:calendar.get(Calendar.MONTH)+1;
	}
	public void setYear(String propertyName, Integer value) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  if (value==null)
	    return;
		PropertyDescriptor propertyDescriptor = getPropertyDescriptor(propertyName);
	  Calendar calendar = getCalendarFromProperty(propertyDescriptor,true);
		calendar.set(Calendar.YEAR,value);
	  setPropertyFromCalendar(propertyDescriptor,calendar);
	}
	public Integer getYear(String propertyName) throws IntrospectionException,IllegalAccessException,InvocationTargetException
	{
	  Calendar calendar = getCalendarFromProperty(getPropertyDescriptor(propertyName),false);
		return calendar==null?null:calendar.get(Calendar.YEAR);
	}
}
